<?php

namespace App\Services\Project;


use App\Models\Project\Contract;
use App\Models\Project\ContractAttachment;
use App\Models\Project\PaymentAgreement;
use App\Models\Project\PendingBill;
use App\Models\Project\Progress;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class ContractService
{

    /**
     * 校验成本
     * @param $request
     * @return array
     * @Author: hql <858566651@qq.com>
     * @DateTime: 2021/12/20 21:23
     */
    public function validateCost($request)
    {
        $message = [];
        $costs = $request->input('cost');
        if (!$costs) {
            return $message;
        }

        $finance_category_ids = $costs['finance_category_id'] ?? [];
        $amount_collect = $costs['amount'] ?? [];

        foreach ($finance_category_ids as $key => $finance_category_id) {

            if ($key == 0 && count($finance_category_ids) == 1 && !$finance_category_id && !$amount_collect[$key]) {
                break;
            } else {
                if (intval($finance_category_id) < 0) {
                    $message[] = '请选择费用类别';
                    break;
                }
                if (!is_numeric($amount_collect[$key]) || $amount_collect[$key] <= 0) {
                    $message[] = '发生费用金额必须是数字切必须大于0';
                    break;
                }
            }
        }
        return $message;
    }

    /**
     * 校验付款约定
     * @param $request
     * @return array|void
     * @Author: hql <858566651@qq.com>
     * @DateTime: 2021/12/20 21:22
     */
    public function validatePaymentAgreement($request)
    {
        $message = [];
        $payment_agreements = $request->input('payment_agreement');

        $percentages = $payment_agreements['percentage'] ?? [];
        $price_collect = $payment_agreements['price'] ?? [];
        $payment_term_ids = $payment_agreements['payment_term_id'] ?? [];

        if (!$payment_agreements) {
            return [
                ['请填写付款约定'],
            ];
        }
        foreach ($percentages as $key => $percentage) {
            if (intval($percentage) < 0) {
                $message[] = '请填写付款百分比且必须是数字';
                break;
            }
            if (!isset($price_collect[$key]) || !is_numeric($price_collect[$key])) {
                $message[] = '请填写付款金额付';
                break;
            }
            if (!isset($payment_term_ids[$key]) || intval($payment_term_ids[$key]) <= 0) {
                $message[] = '请选择付款条件';
                break;
            }

        }
        return $message;
    }

    /**
     * 数据校验
     * @param $request
     * @return array|void
     * @Author: hql <858566651@qq.com>
     * @DateTime: 2021/12/20 21:22
     */
    public function validates($request)
    {
        $cost_validate = $this->validateCost($request);
        $payment_agreement_validate = self::validatePaymentAgreement($request);
        return array_merge($cost_validate, $payment_agreement_validate);

    }

    /**
     * 项目规模 存json
     * @param $request
     * @return array
     * @Author: hql <858566651@qq.com>
     * @DateTime: 2021/12/20 21:43
     */
    public function buildScaleAttributes($request)
    {
        $scales = $request->input('scale');
        if (!$scales) {
            return [];
        }

        $data = [];
        $names = $scales['name'] ?? [];
        $remarks = $scales['remark'] ?? [];
        foreach ($names as $key => $item) {
            $data[] = [
                'name'   => $item,
                'remark' => $remarks[$key] ?? '',
            ];
        }
        return $data;
    }

    /**
     * 发生费用
     * @param $request
     * @return array
     * @Author: hql <858566651@qq.com>
     * @DateTime: 2021/12/20 21:44
     */
    public function buildCostAttributes($request, $contract)
    {

        $data = [];
        $costs = $request->input('cost');
        $cost_ids = $costs['cost_id'] ?? [];
        $finance_category_ids = $costs['finance_category_id'] ?? [];
        $amount_collect = $costs['amount'] ?? [];
        foreach ($finance_category_ids as $key => $finance_category_id) {
            if ($key == 0 && count($finance_category_ids) == 1 && !$finance_category_id && !$amount_collect[$key]) {
                break;
            }

            $id = $cost_ids[$key] ?? 0;

            $tmp = [
                'contract_id'         => $contract->id,
                'stage'               => '意向阶段',
                'finance_category_id' => $finance_category_id,
                'amount'              => $amount_collect[$key],
                'agent_id'            => Auth::id(),
                'operator_uid'        => Auth::id(),
                'created_at'          => now(),
                'updated_at'          => now(),
            ];
            if ($id) {
                unset($tmp['created_at']);
                $tmp['id'] = $id;
                $data['update'][$id] = $tmp;
            } else {
                $data['create'][] = $tmp;
            }
        }
        return $data;
    }

    /**
     * 付款约定
     * @param $request
     * @return array
     * @Author: hql <858566651@qq.com>
     * @DateTime: 2021/12/20 21:44
     */
    public function buildPaymentAgreementAttributes($request, $contract)
    {
        $data = [];
        $payment_agreements = $request->input('payment_agreement') ?? [];
        $percentages = $payment_agreements['percentage'] ?? [];
        $price_collect = $payment_agreements['price'] ?? [];
        $payment_term_ids = $payment_agreements['payment_term_id'] ?? [];
        $payment_agreement_ids = $payment_agreements['payment_agreement_id'] ?? [];

        foreach ($percentages as $key => $percentage) {
            $tmp = [
                'contract_id'     => $contract->id,
                'key'             => $key + 1,
                'percentage'      => $percentage,
                'price'           => $price_collect[$key],
                'payment_term_id' => $payment_term_ids[$key],
                'created_at'      => now(),
                'updated_at'      => now(),
            ];
            $id = $payment_agreement_ids[$key] ?? 0;
            if ($id) {
                unset($tmp['created_at']);
                $tmp['id'] = $id;
                $data['update'][] = $tmp;
            } else {
                $data['create'][] = $tmp;
            }
        }
        return $data;
    }

    /**
     * 构建合同属性
     * @param $request
     * @return array
     * @Author: hql <858566651@qq.com>
     * @DateTime: 2021/12/22 21:18
     */
    public function buildContractAttributes($request)
    {
        $scale_data = $this->buildScaleAttributes($request);

        return [
            'project_name'              => $request->input('project_name'),
            'project_type_id'           => $request->input('project_type_id'),
            'scale_data'                => json_encode($scale_data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE),
            'sign_company_id'           => $request->input('sign_company_id'),
            'other_company_name'        => $request->input('other_company_name') ?? '',
            'other_company_contact'     => $request->input('other_company_contact') ?? '0',
            'other_company_mobile'      => $request->input('other_company_mobile') ?? '',
            'signed_at'                 => $request->input('signed_at'),
            'contract_amount'           => $request->input('contract_amount'),
            'pay_times'                 => $request->input('pay_times') ?? 0,
            'required_finish_at'        => $request->input('required_finish_at'),
            'owner_unit'                => $request->input('owner_unit') ?? '',
            'owner_contact'             => $request->input('owner_contact') ?? '',
            'owner_mobile'              => $request->input('owner_mobile') ?? '',
            'owner_address'             => $request->input('owner_address') ?? '',
            'province_id'               => $request->input('province_id') ?? 0,
            'city_id'                   => $request->input('city_id') ?? 0,
            'area_id'                   => $request->input('area_id') ?? 0,
            'detail_address'            => $request->input('detail_address') ?? '',
            'cooperation_mode'          => $request->input('cooperation_mode') ?? 0,
            'source'                    => $request->input('source') ?? 0,
            'source_contact_id'         => $request->input('source_contact_id') ?? 0,
            'source_company'            => $request->input('source_company') ?? '',
            'source_mobile'             => $request->input('source_mobile') ?? '',
            'professional_director_uid' => $request->input('professional_director_uid') ?? 0,
            'contract_director_uid'     => $request->input('contract_director_uid') ?? 0,
            'inner_docking_uid'         => $request->input('inner_docking_uid') ?? 0,
        ];

    }

    /**
     * 创建或更新合同
     * @param $request
     * @param null $contract
     * @return bool
     * @Author: hql <858566651@qq.com>
     * @DateTime: 2021/12/22 21:17
     */
    public function updateOrCreate($request, $contract = null)
    {
        $contract_data = $this->buildContractAttributes($request);

        $progress = intval($request->input('is_submit_approval')) ? ProgressStatusService::PROFESSIONAL_DIRECTOR_APPROVING : ProgressStatusService::CONTRACT_TEMPORARY_STORAGE;
        $contract_data['progress_id'] = get_progress_id($progress);
        DB::beginTransaction();
        if ($contract instanceof Contract) {
            $contract->update($contract_data);
        } else {
            $contract_data['operator_uid'] = Auth::id();
            $contract = Contract::create($contract_data);
            if (!$contract) {
                DB::rollBack();
                return false;
            }
        }

        // 发生费用
        $pending_bills = $this->updateOrCreatePendingBills($request, $contract);
        if (!$pending_bills) {
            DB::rollBack();
            return false;
        }
        // 付款约定
        $payment_agreements = $this->updateOrCreatePaymentAgreements($request, $contract);
        if (!$payment_agreements) {
            DB::rollBack();
            return false;
        }

        if ($request->input('file')) {
            AttachmentService::createOrUpdate($contract->id,'合同',$request->input('file'));
        }

        $this->log($contract, '添加意向合同', '合同进度：' . $progress);
        DB::commit();

        return true;
    }

    /**
     * 创建或更新发生费用
     * @param $request
     * @param $contract
     * @return bool
     * @Author: hql <858566651@qq.com>
     * @DateTime: 2021/12/22 21:17
     */
    public function updateOrCreatePendingBills($request, $contract)
    {
        $pending_bills = self::buildCostAttributes($request, $contract);
        if (!$pending_bills && !$contract->pendingBills->count()) {
            return true;
        }
        DB::beginTransaction();
        if (!$pending_bills && $contract->pendingBills->count()) {
            $res = PendingBill::query()->where('contract_id', $contract->id)->delete();
            if (!$res) {
                DB::rollBack();
                return false;
            }
        }

        $create_data = $pending_bills['create'] ?? [];

        if ($create_data) {
            $res = PendingBill::insert($create_data);
            if (!$res) {
                DB::rollBack();
                return false;
            }
        }
        $update_date = $pending_bills['update'] ?? [];
        if ($update_date) {
            if (count($update_date) != $contract->pendingBills->count()) {
                $update_date_ids = array_column($update_date, 'id');
                $res = PendingBill::query()->whereNotIn('id', $update_date_ids)->delete();
                if (!$res) {
                    DB::rollBack();
                    return false;
                }
            }

            $res = PendingBill::batchUpdate('pm_pending_bills', $update_date);
            if (!$res) {
                DB::rollBack();
                return false;
            }
        }
        DB::commit();
        return true;
    }

    /**
     * 创建或更新付款约定
     * @param $request
     * @param $contract
     * @return bool
     * @Author: hql <858566651@qq.com>
     * @DateTime: 2021/12/22 21:17
     */
    public function updateOrCreatePaymentAgreements($request, $contract)
    {
        $payment_agreements = self::buildPaymentAgreementAttributes($request, $contract);
        if (!$payment_agreements && !$contract->paymentAgreements->count()) {
            return true;
        }
        DB::beginTransaction();
        if ($contract->paymentAgreements->count() && !$payment_agreements) {
            $res = PaymentAgreement::query()->where('contract_id', $contract->id)->delete();
            if (!$res) {
                DB::rollBack();
                return false;
            }
        }
        $create_data = $payment_agreements['create'] ?? [];
        $res = PaymentAgreement::insert($create_data);
        if (!$res) {
            DB::rollBack();
            return false;
        }
        $update_date = $payment_agreements['update'] ?? [];
        if ($update_date) {
            if (count($update_date) != $contract->paymentAgreements->count()) {
                $update_date_ids = array_column($update_date, 'id');
                $res = PaymentAgreement::query()->whereNotIn('id', $update_date_ids)->delete();
                if (!$res) {
                    DB::rollBack();
                    return false;
                }
            }

            $res = PaymentAgreement::batchUpdate('pm_payment_agreements', $update_date);
            if (!$res) {
                DB::rollBack();
                return false;
            }
        }

        DB::commit();
        return true;
    }


    public function log($contract, $title, $remark = '')
    {
        return $contract->logs()->create(['title' => $title, 'remark' => $remark, 'operator_uid' => Auth::id()]);
    }
}
